/** Author: JTrapp@Google.com
* (c) 07.01.2008 */

/**
* Access to the map
* @type GMap2
*/
var map;
/**
* Access to the Geocoder
* @type GClientGeocoder
*/
var geocoder;

var myIcon;

var idIdx;
var nameIdx;
var addr1Idx;
var addr2Idx;
var cityIdx;
var postalIdx;
var countryIdx;
var phoneIdx;
var phone2Idx;
var mobileIdx;
var faxIdx;
var homepageIdx;
var emailIdx;
var paymentTypesIdx;
var categoriesIdx;
var descriptionIdx;
var regionIdIdx;
var lngIdx;
var latIdx;
var autocluster= false;



/** Create the icon*/
function createIcon(){
    var iconURL = prefs.getString("iconURL");
    if (iconURL!=null && iconURL.length>0){
        prefs.getMsg("iconURL");
        myIcon = new google.maps.Icon();
        myIcon.iconSize = new google.maps.Size(prefs.getString("iconWidth"), prefs.getString("iconHeight"));
        myIcon.iconAnchor = new google.maps.Point(prefs.getString("iconAnchorX"), prefs.getString("iconAnchorY"));
        myIcon.infoWindowAnchor = new google.maps.Point(prefs.getString("iconWindowX"),prefs.getString("iconWindowY"));
        myIcon.infoWindowAnchor = myIcon.iconAnchor;
        myIcon.image = _IG_GetImageUrl(iconURL);
    }
}

/** 
* Get the index for a certain keyword in an array of strings.
*/
function getIdByName(stringArray, key) {
    for (var i =0, string; string = stringArray[i]; i++) {
        if (string == key) {
            return i;
        }
    }
    return -1;
}

function initIndices(header){
    idIdx = getIdByName(header, "STORE_CODE");
    nameIdx = getIdByName(header, "NAME");
    addr1Idx = getIdByName(header, "ADDRESS_LINE_1");
    addr2Idx = getIdByName(header, "ADDRESS_LINE_2");
    cityIdx = getIdByName(header, "CITY");
    postalIdx = getIdByName(header, "POSTAL_CODE");
    countryIdx = getIdByName(header, "COUNTRY_CODE");
    phoneIdx = getIdByName(header, "MAIN_PHONE");
    phone2Idx = getIdByName(header, "ALT_PHONE");
    mobileIdx = getIdByName(header, "MOBILE_PHONE");
    faxIdx = getIdByName(header, "FAX_PHONE");
    homepageIdx = getIdByName(header, "HOME_PAGE");
    emailIdx = getIdByName(header, "EMAIL");
    paymentTypesIdx = getIdByName(header, "PAYMENT_TYPES");
    categoriesIdx = getIdByName(header, "CATEGORIES");
    descriptionIdx = getIdByName(header, "DESCRIPTION");
    regionIdIdx = getIdByName(header, "REGION_ID"); // Added for doing staging
    if (prefs.getMsg("autocluster")=="true"){
        autocluster= true;
    }
    latIdx =  getIdByName(header, "LATITUDE");  // For writing the result
    lngIdx =  getIdByName(header, "LONGITUDE");
}

function SF_init() {
    //_gel("SF_div").innerHTML="<div id=\"mapDiv\" class=\"map\">"+prefs.getMsg("loadingMap")+"</div><br/><div id=\"status\" class=\"status\"><div>";
    map = new google.maps.Map2(_gel("SF_map"));
    map.setCenter(new google.maps.LatLng(41.875696,-87.624207), 3); 
    geocoder = new google.maps.ClientGeocoder();        
    createIcon();
    
    var requestURL = prefs.getString("storeListURL");
    if (prefs.getBool("debug")){ 
        google.maps.Log.writeUrl( requestURL);      
    }
    var len = requestURL.length;
    var spreadsheetsBaseURL = "http://spreadsheets.google.com/";
    var suffix = requestURL.substring(len-4, len);
    
    if ((suffix == ".csv")||(suffix == ".txt")){
        readCSV(requestURL);
    }else if (requestURL.substring(0,spreadsheetsBaseURL.length) == spreadsheetsBaseURL){
    readSpreadsheet(requestURL);
}
initMapControls();
}


function readCSV(requestURL){
    //google.maps.Log.write( "<a href=\""+requestURL+"\">Fetching storelist.</a>");
    _IG_FetchContent(requestURL, function (responseText) { 
        var lines = responseText.split("\n");
        var startIdx=0;
        while (startIdx<lines.length&&lines[startIdx].substring(0,"STORE_CODE".length)!="STORE_CODE"){
            if (lines[startIdx] == "AUTOCLUSTER"){ // if autocluster is in one of the introductiory lines
                autocluster=true;
            }
            startIdx++;
        }
        if (startIdx<lines.length){
            initIndices (lines[startIdx++].split("\t"));
            var numShops = lines.length-startIdx;
            if (prefs.getBool("debug")){ 
                google.maps.Log.writeHtml( "<a href=\""+requestURL+"\">"+numShops+ " Shops loaded.</a>");      
            }
            var bounds = new google.maps.LatLngBounds( );    
            for (var i = startIdx; i<numShops; i++) {
                var c = lines[i].split("\t");
                createMarkerCSV(c, bounds, i);               
            }
            
            map.setCenter(bounds.getCenter(), map.getBoundsZoomLevel(bounds));
            //google.maps.Log.writeHtml( "<a href=\""+requestURL+"\">"+numShops+ " addresses loaded.</a>");     
            
        } else {
            google.maps.Log.writeHtml( "<a href=\""+requestURL+"\">Illegal format in shoplist.</a>");
            google.maps.Log.write(response);
    }
});
}


function readSpreadsheet(requestURL){
    _IG_FetchXmlContent(requestURL, function (response) {  
        if (response == null || typeof(response) != "object" ||
        response.firstChild == null){
            _gel("SF_title").innerHTML = "Error <a href=\""+requestURL+"\"/>"+requestURL+"</a>";
           // _gel("content").innerHTML ="<a href=\""+url+"\"/>"+url+"</a>";
        } else {
        
            _IG_SetTitle(getNodeValue(response, "title"));
        if (prefs.getBool("debug")){ 
            google.maps.Log.write("updated:"+getNodeValue(response, "updated"));
        }
        var bounds = new google.maps.LatLngBounds( );    
        var entries = response.getElementsByTagName("entry");
        if (entries!=null){
            if (prefs.getBool("debug")){ 
                google.maps.Log.write( "Geocoding"+entries.length+" addresses.");
            }
            for (var i = 0; i < entries.length ; i++) { 
                // For each <food> node, get child nodes.
                createMarkerSpreadsheetGData(entries.item(i), bounds, i);
            }
            
            map.setCenter(bounds.getCenter(), map.getBoundsZoomLevel(bounds));
            
        } else {
            google.maps.Log.writeHtml( "<a href=\""+requestURL+"\">Illegal format in shoplist.</a>");
            google.maps.Log.write(response);
    }
    }
},0 );
}

function initMapControls() {
    map.addControl(new google.maps.SmallMapControl());
    map.setMapType(G_HYBRID_MAP);
    if (prefs.getBool("showMapTypeControls")) { 
        map.addControl(new google.maps.MapTypeControl());
    }
    //
    //    if (prefs.getBool("showSearchControls")){
    //        // create a local search control and add it to your map
    //        google.load("uds", "1");
    //
    //        var lsc = new google.maps.LocalSearch(); 
    //        map.addControl(new google.maps.LocalSearch());
    //    }
    
}


/**
* Create a marker on the map for the given address. 
*/
function createMarkerCSV(cells, bounds, rowNr) {
    createMarker(
        cells[nameIdx],  cells[descriptionIdx], cells[homepageIdx], 
        cells[addr1Idx], cells[addr2Idx], cells[cityIdx],cells[postalIdx],cells[countryIdx], 
        cells[phoneIdx],cells[faxIdx],bounds, rowNr);
}


function createMarkerSpreadsheetGData(entry, bounds, rowNr) {
    createMarker(
        getNodeValue(entry, "gsx:name"), getNodeValue(entry, "gsx:description"),
        getNodeValue(entry, "gsx:homepage"), getNodeValue(entry, "gsx:addressline1"),
        getNodeValue(entry, "gsx:addressline2"), getNodeValue(entry, "gsx:city"),
        getNodeValue(entry, "gsx:postalcode"),getNodeValue(entry, "gsx:countrycode"), 
        getNodeValue(entry, "gsx:mainphone"),getNodeValue(entry, "gsx:faxphone"), 
        bounds, rowNr);
}

function createMarker(name, 
    description, homepage, addressline1, addressline2, city,
    postalcode, countrycode, mainphone, faxphone,
    bounds, rowNr) {
var address = addressline1+" "+addressline2+","+postalcode+","+countrycode;

geocoder.getLocations(address, function(response) {
    //google.maps.Log.write( "Geocoding "+address+" address on line "+rowNr);
    if (!response ) {
        google.maps.Log.write("Failed geocoding address "+address+" on line "+rowNr);
    } else if (response.Status.code != 200) {
        google.maps.Log.write("Failed geocoding "+address +" with status "+response.Status.code+" on line "+rowNr);
    } else {
        //google.maps.Log.write( "Geocoding "+address+" address...");

        var point = new google.maps.LatLng(response.Placemark[0].Point.coordinates[1], response.Placemark[0].Point.coordinates[0]);
        var marker = new google.maps.Marker(point, {icon:myIcon});
        GEvent.addListener(marker, "click", function() {
            marker.openInfoWindowHtml(
            "<h1 class=\"popup\"><a href=\""+homepage+"\">"+name+"</a></div>"+
            "<p class=\"popup\">"+description+"</p>"+
            "<table><tr><td>"+addressline1+"</td><td rowspan=\"4\">"+/*put image here*/"</td></tr>"+
            (addressline2.length>0?"<tr><td>"+addressline2+"</td></tr>":"")+
            "<tr><td>"+city+","+ postalcode+"</td></tr>"+
            "<tr><td>Phone: "+mainphone+"</td></tr>"+
            "<tr><td>Fax: "+faxphone+"</td></tr>"+
            "</table>"
            , {maxWidth : 120});
        });   
        map.addOverlay(marker);
        var accuracy =  response.Placemark[0].AddressDetails.Accuracy;        
        if (prefs.getBool("debug")){ 
            google.maps.Log.write( "Geocoded "+address+" address  on line "+rowNr+" (Accuracy: "+accuracy+")");
            }
        bounds.extend(point);
        map.setCenter(bounds.getCenter(), map.getBoundsZoomLevel(bounds));

    }
    });
}

/**
* Retrieve the first child element for a given tag.
* this method will only look for direct childs. No grandchilds will be found.
* For some an unknown reason, I didn't get the standard getElementsByTagNameNS 
* to work. If you know how, please substitute and let me know.

* @param {Element} element Some Dom element
* @param {String} tagname The child elements tag name, which may include the namespace prefix.
* @return {Node}Child element or the String "[<"+tagname+"> null]" or "[<"+tagname+"> not found]". 
*/
function getNodeValue(element, tagname) {
    var nodeList = element.childNodes;
    for (var i = 0, node; node = nodeList[i]; i++) {
        if (node.nodeName == tagname) {
            if (node.firstChild!=null){
                //google.maps.Log.write(tagname+": "+node.firstChild.nodeValue);
                return node.firstChild.nodeValue;
            } 
            else {
                return "";
            }
        } else {
        var result = getNodeValue(node, tagname);
        if (result!=null)
            return result;
        
    }
}
return null;
}


// Create a directions object and register a map and DIV to hold the 
// resulting computed directions

function getDirections(from, to) {
    var directionsPanel = document.getElementById("directions");
    var directions = new google.maps.Directions(map, directionsPanel);
    directions.load(from+" to "+to);
}

